package com.kexuexiong.demo.bear.controller.person;

import cn.hutool.core.bean.BeanUtil;
import com.alibaba.csp.sentinel.annotation.SentinelResource;
import com.alibaba.csp.sentinel.slots.block.BlockException;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.kexuexiong.demo.bear.common.dto.Result;
import com.kexuexiong.demo.bear.common.multiDataSource.annotation.SwitchDataSource;
import com.kexuexiong.demo.bear.entity.Person;
import com.kexuexiong.demo.bear.service.PersonService;
import com.kexuexiong.demo.common.dto.PersonDTO;
import com.kexuexiong.demo.common.feignProvider.baseService.person.PersonFeignClient;
import io.seata.spring.annotation.GlobalTransactional;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.v3.oas.annotations.Parameter;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.web.bind.annotation.*;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author kexuexiong
 * @since 2023-03-22
 */
@RestController
@RequestMapping("/person")
@Api(tags = {"person"})
@Slf4j
public class PersonController {


    @Autowired
    private PersonService personService;


    @Autowired
    private PersonFeignClient personFeignClient;


    @GetMapping(value = "/list")
    @ApiOperation(value = "list", notes = "列表")
    @Cacheable("person")
    public Result list(@Parameter(name = "current") @RequestParam(required = false) Integer current, @Parameter(name = "pageSize") @RequestParam(required = false) Integer pageSize) {
        if (current == null) {
            current = 1;
        }
        if (pageSize == null) {
            pageSize = 10;
        }
        Page<Person> aPage = personService.page(new Page<>(current, pageSize));

        return Result.success(aPage);
    }

    @GetMapping(value = "/listV2")
    @ApiOperation(value = "listV2", notes = "列表")
    @SwitchDataSource(value = "demo-02")
    public Result listV2(@Parameter(name = "current") @RequestParam(required = false) Integer current, @Parameter(name = "pageSize") @RequestParam(required = false) Integer pageSize) {
        if (current == null) {
            current = 1;
        }
        if (pageSize == null) {
            pageSize = 10;
        }
        Page<Person> aPage = personService.page(new Page<>(current, pageSize));

        return Result.success(aPage);
    }

    @GetMapping(value = "/{id}")
    @ApiOperation(value = "获取person", notes = "根据id获取person")
    public Result<Person> getById( @PathVariable("id") String id) {
        return Result.success(personService.getById(id));
    }

    @PostMapping(value = "/create")
    @ApiOperation(value = "create", notes = "创建person")
    @GlobalTransactional
    public Result<Object> create(@Parameter(name = "params") @RequestBody Person params) {
        personService.saveV2(params);
        return Result.success();
    }

    @PostMapping(value = "/v2Create")
    @ApiOperation(value = "v2Create", notes = "v2Create 创建person")
    @GlobalTransactional(name = "personCreate",rollbackFor = Exception.class)
    @SentinelResource(value = "v2Create",fallback = "v2CreateBlockHandler",blockHandler = "v2CreateBlockHandler")
    public Result<Object> v2Create(@Parameter(name = "params") @RequestBody Person params) {
        personService.saveV2(params);
        params.setId(null);
        PersonDTO personDTO = new PersonDTO();
        BeanUtil.copyProperties(params,personDTO);
        personFeignClient.create(personDTO);
        return Result.success();
    }

    public Result<Object> v2CreateFallbackHandler(Person params, Throwable ex) {
        log.info("v2CreateFallbackHandler:{}",params);
        return Result.success("降级！");
    }

    public Result<Object> v2CreateBlockHandler(Person params, BlockException ex) {
        log.info("v2CreateBlockHandler:{}",params);
        return Result.success("限流！");
    }


    @PostMapping(value = "/v3reate")
    @ApiOperation(value = "v3reate", notes = "v3reate 创建person")
    @GlobalTransactional(name = "personCreate",rollbackFor = Exception.class)
    public Result<Object> v3reate(@Parameter(name = "params") @RequestBody Person params) {
        personService.saveV2(params);
        return Result.success();
    }

    @PostMapping(value = "/delete/{id}")
    @ApiOperation(value = "delete", notes = "删除")
    public Result<Object> delete(@Parameter(name = "id") @PathVariable("id") String id) {
        personService.removeById(id);
        return Result.success();
    }

    @PostMapping(value = "/update")
    @ApiOperation(value = "update", notes = "更新")
    public Result<Object> update(@Parameter(name = "params") @RequestBody Person params) {
        personService.updateById(params);
        return Result.success();
    }
}
